package com.hyz.advice;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyz.pojo.asset.Asset;
import com.hyz.pojo.asset.AssetStatus;
import com.hyz.pojo.assetAllocation.AssetAllocation;
import com.hyz.pojo.assetImport.AssetImport;
import com.hyz.pojo.assetImport.AssetImportResult;
import com.hyz.pojo.assetLog.AssetLog;
import com.hyz.pojo.assetOutbound.AssetOutbound;
import com.hyz.pojo.assetSecondment.AssetSecondment;
import com.hyz.pojo.assetSecondment.AssetSecondmentResult;
import com.hyz.pojo.repositoryAsset.RepositoryAsset;
import com.hyz.pojo.secondmentLog.SecondmentLog;
import com.hyz.service.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.Date;

/**
 * @author HGD
 * @date 2022/10/8 16:42
 */
@Component
@Aspect
public class LogAdvice {
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private AssetImportService assetImportService;
    @Autowired
    private AssetSecondmentService asService;
    @Autowired
    private AssetOutboundService aoService;
    @Autowired
    private AssetService assetService;
    @Autowired
    private AssetAllocationService aaService;
    @Autowired
    private AssetMaintenanceService amService;
    @Autowired
    private RepositoryAssetService raService;

    /**
     * 资产入库
     */
    @Pointcut("execution(* com.hyz.controller.RepoManagerController.updateAssetImport(..))")
    private void assetImportPointcut() {
    }

    @Around("assetImportPointcut()")
    private Object insertAssetLog(ProceedingJoinPoint pjp) throws Throwable {
        Object proceed = pjp.proceed();
        // 1. 当insertAssetImport方法执行成功时候，获取方法传入的所有参数
        Object[] args = pjp.getArgs();
        AssetImportResult result = (AssetImportResult) args[1];
        // 2. 判断资产入库申请是否成功
        if (result.equals(AssetImportResult.SUCCEEDED)) {
            Long assetImportId = (Long) args[0];
            // 3. 根据参数获取对应的资产入库申请
            AssetImport assetImport = assetImportService.getById(assetImportId);

            // 3. 数据类型转换，转变成资产日志
            AssetLog assetLog = AssetLog.builder()
                    .assetId(assetImport.getAssetId())
                    .repositoryId(assetImport.getRepositoryId())
                    .result(assetImport.getResult().getValue())
                    .build();
            // 4. 使用 rabbitMQ 将数据传输至 AssetLog 中
            rabbitTemplate.convertAndSend("assetLog", JSON.toJSONString(assetLog));

            RepositoryAsset repositoryAsset = new RepositoryAsset();
            repositoryAsset.setAssetId(assetImport.getAssetId());
            repositoryAsset.setRepositoryId(assetImport.getRepositoryId());
            raService.save(repositoryAsset);
        }
        return proceed;
    }

    /**
     * 资产分配
     */
    @Pointcut("execution(* com.hyz.controller.AssetManagerController.amUpdateAssetSecondment(..))")
    private void assetSecondmentLog() {
    }

    @Around("assetSecondmentLog()")
    public Object insertSecondmentLog(ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        Long assetSecondmentId = (Long) args[0];
        AssetSecondmentResult result = (AssetSecondmentResult) args[1];
        Object proceed = pjp.proceed();
        if (result.equals(AssetSecondmentResult.ASSET_MANAGER_AGREE)) {
            AssetSecondment assetSecondment = asService.getById(assetSecondmentId);
            QueryWrapper<AssetOutbound> aoWrapper = new QueryWrapper<>();
            aoWrapper.lambda().eq(AssetOutbound::getAssetSecondmentId, assetSecondmentId);
            AssetOutbound assetOutbound = aoService.getOne(aoWrapper);
            // 1. 创建资产分配
            AssetAllocation assetAllocation = new AssetAllocation();
            assetAllocation.setAssetId(assetOutbound.getAssetId());
            assetAllocation.setApplicantId(assetSecondment.getApplicantId());
            assetAllocation.setAssetManagerId(assetOutbound.getAssetManagerId());
            aaService.save(assetAllocation);

            // 2. 修改资产状态
            Asset asset = assetService.getById(assetOutbound.getAssetId());
            asset.setStatus(AssetStatus.SECONDMENT);
            assetService.saveOrUpdate(asset);

            // 3. 创建资产历史
            Date date30 = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000 * 30L);
            SecondmentLog secondmentLog = SecondmentLog.builder()
                    .assetId(assetOutbound.getAssetId())
                    .applicantId(assetSecondment.getApplicantId())
                    .assetManagerId(assetOutbound.getAssetManagerId())
                    .returnTime(new Date(date30.getTime()))
                    .result(assetSecondment.getStatus().getValue()).build();
            String message = JSON.toJSONString(secondmentLog);
            rabbitTemplate.convertAndSend("secondmentLog", message);

            // 4. 删除资产与仓库关系
            QueryWrapper<RepositoryAsset> raWrapper = new QueryWrapper<>();
            raWrapper.lambda().eq(RepositoryAsset::getAssetId, asset.getId());
            raService.remove(raWrapper);
        }
        // 5. 删除出库申请
        QueryWrapper<AssetOutbound> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AssetOutbound::getAssetSecondmentId, assetSecondmentId);
        aoService.remove(wrapper);
        return proceed;
    }
}
